package com.wb.core12线程;

import com.wb.core12线程.练习.Test;

/**
 * @author 黄衡熙
 * @version 1.0
 */
public class Test09_生产者消费者问题 {
    public static void main(String[] args) {
        ProductPool pool = new ProductPool();
        // 定义生产者
        Product p1 = new Product(pool, "生产者p1");
        Product p2 = new Product(pool, "生产者p2");
        Product p3 = new Product(pool, "生产者p3");
        // 定义消费者
        Consumer c1 = new Consumer(pool, "消费者c1");
        Consumer c2 = new Consumer(pool, "消费者c2");
        // 启动线程
        p1.start();
        p2.start();
        p3.start();
        c1.start();
        c2.start();
    }


}
//缓冲池
class ProductPool {
   //定义当前商品数量
   private int num;
    //缓冲池中的商品数量最大值
    private static final int Max=20;
    /*生产者生产商品到缓冲池中
    * */
    public int put(){
        num++;
        return num;
    }
    /*
    * 消费者从缓冲池中取商品
    * */
    public int get(){
        num--;
        return num;
    }
    /*
    * 判断当前商品是否已满
    * */
    public boolean isFull(){
        return this.num==Max;
    }
    /*
    * 判断当前商品是否为空
    * */
    public boolean isEmpty(){
        return this.num==0;
    }
}
class Product extends Thread {
    private ProductPool pool;
    private String name;

    public Product(ProductPool pool, String name) {
        this.pool = pool;
        this.name = name;
    }
    public void run() {
     while (true) {
         synchronized (pool) {
             if (pool.isFull()) {
                 System.out.println("当前商品已满，需等待消费者消费");
                 try {
                     pool.wait();
                 } catch (InterruptedException e) {
                     throw new RuntimeException(e);
                 }
             }else{
                 int num = pool.put();
                 System.out.println(this.name+"生产了"+num+"件商品");
                 pool.notifyAll();
             }
         }
     }
    }
}
class Consumer extends Thread {
    private ProductPool pool;
    private String name;
    public Consumer(ProductPool pool, String name) {
        this.pool = pool;
        this.name = name;
    }
    @Override
    public void run() {
        while (true) {
            synchronized (pool) {
                // 判断当前缓冲区中商品是否为空
                if (pool.isEmpty()) {
                    try {
                        // 如果为空,则需要等待生产者进行生产
                        System.out.println("当前缓冲区中没有商品,需要等待生产者进行生产");
                        pool.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    // 如果不为空,则消费者消费商品
                    int num = pool.get();
                    System.out.println(this.name + "消费了一件商品,当前缓冲区中商品数量为:" + num);
                    // 当消费者消费了之后,需要将等待的生产者全部唤醒
                    pool.notifyAll();
                }
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

}